import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class Utils {
    public static double getExpresValue(String exp){
        return evalPRN(infixToSuffix(exp));
    }
    // 中缀表达式转逆波兰表达式
    public static String[] infixToSuffix(String exp) {
        List<String> ans = new ArrayList<>();
        LinkedList<Character> stack = new LinkedList<>(); // 存放运算符
        for (int i = 0; i < exp.length(); i++) {
            char c = exp.charAt(i);
            switch (c){
                case '*','/','+','-'->{
                    if(stack.isEmpty()){
                        stack.push(c);
                    } else {
                        if(priority(c)>priority(stack.peek())) {
                            stack.push(c);
                        }else {
                            while (!stack.isEmpty()&&priority(stack.peek()) >= priority(c)) {
                                ans.add(stack.pop()+"");
                            }
                            stack.push(c);
                        }
                    }
                }
                case '(' ->{
                    stack.push(c);
                }
                case ')' ->{
                    while (!stack.isEmpty()&&stack.peek() != '(') {
                        ans.add(stack.pop()+"");
                    }
                    stack.pop();
                }
                default -> {
                    if(i+1<exp.length()) {
                        StringBuilder sb = new StringBuilder();
                        sb.append(c);
                        char c2 = exp.charAt(i+1);
                        if('0'<=c2&&c2<='9') {
                            sb.append(c2);
                            i++;
                        }
                        ans.add(sb.toString());
                    }else {
                        ans.add(c+"");
                    }
                }
            }
        }
        while (!stack.isEmpty()){
            ans.add(stack.pop()+"");
        }
        return ans.toArray(new String[ans.size()]);
    }
    // 逆波兰表达式求值
    private static double evalPRN(String[] tokens) {
        LinkedList<Double> stack = new LinkedList<>();
        for (String t: tokens) {
            switch (t) {
                case "+"->{
                    Double b = stack.pop();
                    Double a = stack.pop();
                    stack.push(a + b);
                }
                case "-"->{
                    Double b = stack.pop();
                    Double a = stack.pop();
                    stack.push(a - b);
                }
                case "*"->{
                    Double b = stack.pop();
                    Double a = stack.pop();
                    stack.push(a * b);
                }
                case "/"->{
                    Double b = stack.pop();
                    Double a = stack.pop();
                    stack.push(a / b);
                }
                default ->{
                    stack.push(Double.parseDouble(t));
                }
            }
        }
        return stack.pop();
    }
    // 返回运算符的优先级
    private static int priority(char c) {
        return switch (c) {
            case '*','/' ->2;
            case '+','-' ->1;
            case '(' -> 0;
            default -> throw new IllegalArgumentException("不合法的运算符");
        };
    }

}
